package com.example.demo.mathtest;

public class Node {
    private String str;
    private Node rChild = null;
    private Node lChild = null;

    public Node(String str) {
        this.str = str;
    }

    public Node(String str, Node lChild, Node rChild) {
        this.str = str;
        this.rChild = rChild;
        this.lChild = lChild;
    }

    public void setChild(Node lChild, Node rChild) {
        this.lChild = lChild;
        this.rChild = rChild;
    }

    public Node getRChild() {
        return rChild;
    }

    public void setRChild(Node rChild) {
        this.rChild = rChild;
    }

    public Node getLChild() {
        return lChild;
    }

    public void setlChild(Node lChild) {
        this.lChild = lChild;
    }

    public String getStr() {
        return str;
    }

    public String getResult() {
        if (hasChild()) {
            switch (str) {
                case "+":
                    return String.valueOf(Integer.parseInt(getLChild().getResult()) + Integer.parseInt(getRChild().getResult()));
                case "-":
                    return String.valueOf(Integer.parseInt(getLChild().getResult()) - Integer.parseInt(getRChild().getResult()));
                case "*":
                    return String.valueOf(Integer.parseInt(getLChild().getResult()) * Integer.parseInt(getRChild().getResult()));
                case "/":
                    if (getRChild().getResult().equals("0")) {
                        while (str.equals("/")) {
                            str = String.valueOf(Ran.getOperator());
                        }
                        return this.getResult();
                    } else if (Integer.parseInt(getLChild().getResult()) % Integer.parseInt(getRChild().getResult()) != 0) {
                        while (str.equals("/")) {
                            str = String.valueOf(Ran.getOperator());
                        }
                        return this.getResult();
                    } else
                        return String.valueOf(Integer.parseInt(getLChild().getResult()) / Integer.parseInt(getRChild().getResult()));
            }
        }
        return str;
    }

    public String toString() {
        String lStr = "", rStr = "", Str = "";
        if (hasChild()) {
            //右子树如果有孩子，说明右子树是一个表达式，而不是数字节点。
            if (getRChild().hasChild()) {
                //判断左邻括号的运算符是否为'/'
                if (str.equals("/")) {
                    //获取右子树的表达式，保留括号
                    rStr = getRChild().toString();
                }
                //判断左邻括号的运算符是否为'*'或'-'
                else if (str.equals("*") || str.equals("-")) {
                    //判断op是否为'+'或'-'
                    if (getRChild().str.equals("+") || getRChild().str.equals("-")) {
                        rStr = getRChild().toString();
                    } else {
                        //获取右子树的表达式，并且去括号
                        rStr = getRChild().toString().substring(1, getRChild().toString().length() - 1);
                    }
                } else {
                    //右子树除此之外都是可以去括号的。
                    rStr = getRChild().toString().substring(1, getRChild().toString().length() - 1);
                }
            } else {
                rStr = getRChild().str;
            }
            //左子树的情况同右子树类似
            if (getLChild().hasChild()) {
                if (str.equals("*") || str.equals("/")) {
                    if (getLChild().str.equals("+") || getLChild().str.equals("-")) {
                        lStr = getLChild().toString();
                    } else {
                        lStr = getLChild().toString().substring(1, getLChild().toString().length() - 1);
                    }
                } else {
                    lStr = getLChild().toString().substring(1, getLChild().toString().length() - 1);
                }
            } else {
                lStr = getLChild().str;
            }
            //获取当前的运算式，并加上括号
            Str = "(" + lStr + str + rStr + ")";
        } else {
            //若没有孩子，说明是数字节点，直接返回数字
            Str = str;
        }
        return Str;
    }

    public boolean hasChild() {
        return lChild != null || rChild != null;
    }
}
